﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Diagnostics;
using Newtonsoft.Json;
using weigh;
using static weigh.BardCodeHooK;
using System.Timers;
using System.Threading;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.IO;
using PrintCore;
using Timer = System.Windows.Forms.Timer;

namespace weigh
{
    public partial class Form1 : Form
    {

        private const string noticeTxt = "请将车辆驶入地磅后，再扫描二维码进行称重";

        // 地磅
        public SerialCommunication myComPort;

        // 扫码
        //  private BardCodeHooK bardCodeHooK;

        // 打印机
        private Printer printer;

        // 扫码及重量信息
        private CodeStruct codeStruct;


        // 定时器
        private System.Timers.Timer myTimer;

        // 定时器委托
        delegate void SetLabelTextCallBack(string text);

        private const string DOMAIN_UEL = "http://test88.jtkji.com/api/weigh/?";

        // 重量
        private double weight = 0;

        // 定时器线程
        private Thread thread;

        // 地磅串口名字
        private string comName = "COM1";

        private int timerNumber = 3;

        [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
        private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int PostMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
        public const int WM_CLOSE = 0x10;


        public int getTimerNumber()
        {
            return this.timerNumber;
        }

        public string getComName()
        {
            return this.comName;
        }

        public Form1()
        {
            InitializeComponent();

            this.printer = PrinterFactory.GetPrinter("POS80 Printer", PaperWidth.Paper80mm);
        }


        private void sannerComboBox()
        {
            this.myComPort = new SerialCommunication();

            this.myComPort.serialPort.PortName = this.comName;
            this.myComPort.serialPort.ReadBufferSize = 256;
            this.myComPort.serialPort.WriteBufferSize = 256;

            //波特率
            this.myComPort.serialPort.BaudRate = 1200;
            //数据位
            this.myComPort.serialPort.DataBits = 8;
            //两个停止位
            this.myComPort.serialPort.StopBits = System.IO.Ports.StopBits.One;
            //无奇偶校验位
            this.myComPort.serialPort.Parity = System.IO.Ports.Parity.None;
            this.myComPort.serialPort.ReadTimeout = 100;
            this.myComPort.serialPort.WriteTimeout = -1;

            this.myComPort.Open();
            if (this.myComPort.IsOpen)
            {
                this.myComPort.DataReceived += new SerialCommunication.EventHandle(commDataReceived);
            }
            myComPort.Open();
        }

        // 313639373030313203022B30313639373030313203022B30

        void commDataReceived(byte[] readBuffer1)
        {
          //  Console.WriteLine(readBuffer1);

            ParseComData com = new ParseComData(readBuffer1);

            string weight = com.covertToString();

            double res = Convert.ToDouble(weight);

            this.weight = res;
            //int weight = Convert.ToInt32(res);

            Console.WriteLine($"重量:{res}");
        }

        private void Form1_Load(object sender, EventArgs e)
        {

            this.myTimer = new System.Timers.Timer(1000);

            this.myTimer.AutoReset = true;

            this.sannerComboBox();

            ThreadStart ts = new ThreadStart(timerCallback);
            this.thread = new Thread(ts);
            this.thread.Name = "timerCallback";

            thread.Start();
        }

        /**
         * 定时器回调函数
         */
        private void timerCallback()
        {
            //设置任务
            this.myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimerElapsed);
        }

        private void SetLabelTex(string text)
        {
            if (this.noticeLabel.InvokeRequired)
            {
                SetLabelTextCallBack stcb = new SetLabelTextCallBack(SetLabelTex);
                this.Invoke(stcb, new object[] { text });
            }
            else
            {
                this.noticeLabel.Text = text;
            }

            if (this.timerNumber <= 0)
            {
                this.myTimer.Stop();

                this.timerNumber = 3;

                // 还原提示label
                this.noticeLabel.Text = noticeTxt;

                // 打印小票
                ThreadStart start = new ThreadStart(() => this.printInfo(this.codeStruct));

                Thread thread = new Thread(start);

                thread.Start();
            }
        }


        private void myTimerElapsed(object sender, ElapsedEventArgs e)
        {
            string txt = "称重中请稍后，" + this.timerNumber + "......";

            SetLabelTex(txt);
           
            this.timerNumber--;
        }

        private void windowClose(object sender, FormClosedEventArgs e)
        {
            //   this.bardCodeHooK.Stop();

            this.myComPort.Close();

            this.thread.Abort();//中止线程
        }

     
        private void onChange(object sender, EventArgs e)
        {
            this.common();

           // Console.WriteLine($"txt:{this.codeText.Text}");
            
        }

        // 处理扫描码
        // 8b115bf1731a436a8393461b9300e2e6|张三&412dbff1d23342719a7083b0ba66a383|李四
        private bool parseCode(out CodeStruct storage)
        {
            storage = default;

            string txt = this.codeText.Text;

            if (0 == txt.Length)
            {
                this.noticeLabel.Text = noticeTxt;

                return false;
            }

            CodeOperation operation = new CodeOperation(txt);

            bool result = operation.check(out storage);

            if (!result)
            {
                Timer timer = new Timer();

                timer.Interval = 3000;

                timer.Tick += new EventHandler(timerTick);

                timer.Start();

                MessageBox.Show("二维码内容错误", "消息");
                return false;
            }

            this.myTimer.Start();

            this.noticeLabel.Text = "称重中请稍后......";

            return true;

        }
        private void timerTick(object sender, EventArgs e)
        {
            KillMessageBox();
            //停止Timer 
            ((Timer)sender).Stop();
        }

        private void KillMessageBox()
        {
            //按照MessageBox的标题，找到MessageBox的窗口 
            IntPtr ptr = FindWindow(null, "消息");
            if (ptr != IntPtr.Zero)
            {
                //找到则关闭MessageBox窗口 
                PostMessage(ptr, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
            }
        }

        private async Task<string> requestCallBack(string url)
        {
            string res =  await HttpRequestHelper.HttpGetRequestAsync(url);

            return res;
        }

        // 请求服务器
        private async void requestServer(CodeStruct storage)
        {

            if (0 >= this.weight)
            {
                MessageBox.Show("重量不能小于零");
                return;

            }

            string url = DOMAIN_UEL + $"sn=123456&mid={storage.mid}&uid={storage.uid}&weight={this.weight}&time={GetTimeStamp()}";

            Func<Task<string>> func_student = new Func<Task<string>>(() => requestCallBack(url));

            string res = await Task.Run(func_student);

            Response response = JsonConvert.DeserializeObject<Response>(res);

           // MessageBox.Show(response.msg);

            this.codeText.Text = null;

            this.noticeLabel.Text = noticeTxt;

            //Console.WriteLine($"返回数据：{res}");

            // 打印小票
            if (0 == response.code)
            {
                storage.weight = this.weight;

                this.codeStruct = storage;
            }

        }


        private void printInfo(CodeStruct codeStruct)
        {
            while(null == this.codeStruct.mid)
            {

            }

            printer.NewRow();
            printer.NewRow();
            printer.PrintText("俊毅农业", Huanent.Printer.Models.FontSize.Huge, StringAlignment.Center);
            printer.NewRow();
            printer.NewRow();
            printer.NewRow();
            printer.PrintText("设备号：1", Huanent.Printer.Models.FontSize.Normal);
            printer.PrintText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Huanent.Printer.Models.FontSize.Normal,stringAlignment: StringAlignment.Far);
            printer.NewRow();
            printer.PrintLine();
            printer.NewRow();
            printer.PrintText("商户姓名", Huanent.Printer.Models.FontSize.Normal);
            printer.PrintText(codeStruct.shopName, Huanent.Printer.Models.FontSize.Normal, offset: 0.35f);

            printer.NewRow();

            printer.PrintText("农户姓名", Huanent.Printer.Models.FontSize.Normal);
            printer.PrintText(codeStruct.frammerName, Huanent.Printer.Models.FontSize.Normal, offset: 0.35f);
            printer.NewRow();

            printer.PrintText("重量");
            printer.PrintText(codeStruct.weight+ "kg", Huanent.Printer.Models.FontSize.Normal, offset: 0.35f);

            printer.Finish();
        }

        private void common()
        {
            CodeStruct storage;

            // 检查扫描码
            if (!this.parseCode(out storage))
            {
                return;
            }


            this.weightTextBox.Text = this.weight.ToString();
            // 解析地磅数据
            // 开始 符号位（+/-）     重量数据          小数点位   异或校验     结束
            //  02   2B          30 30 31 35 34 30      30        31 42       03
            //                    0  0  1  5  4  0.0
            //this.myComPort.

            //Console.WriteLine(this.myComPort.Read(24));

            this.requestServer(storage);

        }

        private void weighingTestsClick(object sender, EventArgs e)
        {

            this.common();
        }

        /// <summary>
        /// 获取时间戳
        /// </summary>
        /// <returns></returns>
        public string GetTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalMilliseconds).ToString();
        }

        private void printTestClick(object sender, EventArgs e)
        {
            printer.NewRow();
            printer.NewRow();
            printer.PrintText("永辉超市", Huanent.Printer.Models.FontSize.Huge, StringAlignment.Center);
            printer.NewRow();
            printer.NewRow();
            printer.NewRow();
            printer.PrintText("操作员：张三");
            printer.PrintText(DateTime.Now.ToString("HH:mm:ss"), stringAlignment: StringAlignment.Far);
            printer.NewRow();
            printer.PrintLine();
            printer.NewRow();
            printer.PrintText("商品");
            printer.PrintText("单价", offset: 0.35f);
            printer.PrintText("数量", offset: 0.65f);
            printer.PrintText("总价", stringAlignment: StringAlignment.Far);
            printer.NewRow();
            printer.PrintLine();
            printer.NewRow();
            printer.PrintText("**长白山大萝卜,跳楼吐血大甩卖，不甜不要钱**", width: 0.35f);
            printer.PrintText("6.00", width: 0.2f, offset: 0.35f);
            printer.PrintText("2.00", width: 0.2f, offset: 0.65F);
            printer.PrintText("12.00", stringAlignment: StringAlignment.Far);
            printer.NewRow();
            printer.NewRow();
            printer.PrintText("大螃蟹", width: 0.35f);
            printer.PrintText("6.000000000001", width: 0.2f, offset: 0.35f);
            printer.PrintText("1", width: 0.2f, offset: 0.65F);
            printer.PrintText("6.000000000001", offset: 0.8f, width: 0.2f);
            printer.NewRow();
            printer.PrintLine();
            printer.NewRow();
           
            printer.NewRow();
            printer.PrintLine();
            printer.NewRow();
            printer.PrintText("感谢光临，欢迎下次再来！", stringAlignment: StringAlignment.Center);
            printer.NewRow();
            printer.Finish();

        }
    }
}
